<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Blorb Writer</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Blorb Writer' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inblorb</a></li><li><a href="index.html#2">Chapter 2: Blorbs</a></li><li><b>Blorb Writer</b></li></ul></div>
<p class="purpose">To write the Blorb file, our main output, to disc.</p>

<ul class="toc"><li><a href="2-bw.html#SP1">&#167;1. Blorbs</a></li><li><a href="2-bw.html#SP6">&#167;6. Big-endian integers</a></li><li><a href="2-bw.html#SP7">&#167;7. Chunks</a></li><li><a href="2-bw.html#SP9">&#167;9. Our choice of chunks</a></li><li><a href="2-bw.html#SP26">&#167;26. Main construction</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Blorbs.</b>"Blorb" is an IF-specific format, but it is defined as a form of IFF file.
IFF, "Interchange File Format", is a general-purpose wrapper format dating back
to the mid-1980s; it was designed as a way to gather together audiovisual media
for use on home computers. (Though Electronic Arts among others used IFF files
to wrap up entertainment material, Infocom, the pioneer of IF at the time, did
not.) Each IFF file consists of a chunk, but any chunk can contain other
chunks in turn. Chunks are identified with initial ID texts four characters
long. In different domains of computing, people use different chunks, and this
makes different sorts of IFF file look like different file formats to the end
user. So we have TIFF for images, AIFF for uncompressed audio, AVI for movies,
GIF for bitmap graphics, and so on.
</p>

<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Main variables:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">total_size_of_Blorb_chunks</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> ditto, but not counting the </span><span class="extract"><span class="extract-syntax">FORM</span></span><span class="comment-syntax"> header or the </span><span class="extract"><span class="extract-syntax">RIdx</span></span><span class="comment-syntax"> chunk</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_indexed_chunks</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>As we shall see, chunks can be used for everything from a few words of
copyright text to 100MB of uncompressed choral music.
</p>

<p class="commentary">Our IFF file will consist of a front part and then the chunks, one after
another, in order of their creation. Every chunk has a type, a 4-character ID
like <span class="extract"><span class="extract-syntax">"AUTH"</span></span> or <span class="extract"><span class="extract-syntax">"JPEG"</span></span>, specifying what kind of data it holds; some
chunks are also given resource numbers which allow the story file to refer
to them as it runs &mdash; the pictures, sound effects and the story file itself
all have unique resource numbers. (These are called "indexed", because
references to them appear in a special <span class="extract"><span class="extract-syntax">RIdx</span></span> record in the front part
of the file &mdash; the "resource index".)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk_file</span><span class="plain-syntax">; </span><span class="comment-syntax"> if the content is stored on disc</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">data_in_memory</span><span class="plain-syntax">; </span><span class="comment-syntax"> if the content is stored in memory</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">length_of_data_in_memory</span><span class="plain-syntax">; </span><span class="comment-syntax"> in bytes; or </span>\(-1\)<span class="comment-syntax"> if the content is stored on disc</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk_type</span><span class="plain-syntax">; </span><span class="comment-syntax"> pointer to a 4-character string</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">index_entry</span><span class="plain-syntax">; </span><span class="comment-syntax"> ditto</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">resource_id</span><span class="plain-syntax">; </span><span class="comment-syntax"> meaningful only if this is a chunk which is indexed</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">byte_offset</span><span class="plain-syntax">; </span><span class="comment-syntax"> from the start of the chunks, which is not quite the start of the IFF file</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">; </span><span class="comment-syntax"> in bytes</span>
<span class="plain-syntax">    </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure chunk_metadata is accessed in 8/ls, 8/tt, 8/tt2, 9/ca, 10/tw and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>It is not legal to have two or more Snd resources with the same number.  The
same goes for Pict resources.  These two linked lists are used to store all the
resource numbers encountered.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">resource_number</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">num</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sound_resource</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">resource_number</span></span>
<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pict_resource</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">resource_number</span></span>
<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">data_resource</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">resource_number</span></span>
</pre>
<ul class="endnotetexts"><li>The structure resource_number is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>And this is used to record alt-descriptions of resources, for the benefit
of partially sighted or deaf users:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">resource_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">description</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure rdes_record is accessed in 5/im, 3/laaf and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Big-endian integers.</b>IFF files use big-endian integers, whereas Inblorb might or might not
(depending on the platform it runs on), so we need routines to write
32, 16 or 8-bit values in explicitly big-endian form:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::four_word</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Writer::four_word</span></span>:<br/><a href="2-bw.html#SP26_2">&#167;26.2</a>, <a href="2-bw.html#SP26_3">&#167;26.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x1000000</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x10000</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x100</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::two_word</span><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x100</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::one_byte</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Writer::one_byte</span></span>:<br/><a href="2-bw.html#SP26_3">&#167;26.3</a>, <a href="2-bw.html#SP26_3_1">&#167;26.3.1</a>, <a href="2-bw.html#SP26_3_2">&#167;26.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fputc</span><span class="plain-syntax">((</span><span class="identifier-syntax">n</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::s_four_word</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Writer::s_four_word</span></span>:<br/><a href="2-bw.html#SP15">&#167;15</a>, <a href="2-bw.html#SP23">&#167;23</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[0] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x1000000</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[1] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x10000</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[2] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x100</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[3] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::s_two_word</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Writer::s_two_word</span></span>:<br/><a href="2-bw.html#SP16">&#167;16</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[0] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> / </span><span class="constant-syntax">0x100</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[1] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::s_one_byte</span><span class="plain-syntax">(</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax">[0] = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">) (</span><span class="identifier-syntax">n</span><span class="plain-syntax">)%</span><span class="constant-syntax">0x100</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Chunks.</b>Although chunks can be written in a nested way &mdash; that's the whole point
of IFF, in fact &mdash; we will always be writing a very flat structure, in
which a single enclosing chunk (<span class="extract"><span class="extract-syntax">FORM</span></span>) contains a sequence of chunks
with no further chunks inside.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>Each chunk is "added" in one of two ways. Either we supply a filename
for an existing binary file on disc which will hold the data we want to
write, or we supply a <span class="extract"><span class="extract-syntax">NULL</span></span> filename and a <span class="extract"><span class="extract-syntax">data</span></span> pointer to <span class="extract"><span class="extract-syntax">length</span></span>
bytes in memory.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::add_chunk_to_blorb</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Writer::add_chunk_to_blorb</span></span>:<br/><a href="2-bw.html#SP13">&#167;13</a>, <a href="2-bw.html#SP14">&#167;14</a>, <a href="2-bw.html#SP15">&#167;15</a>, <a href="2-bw.html#SP16">&#167;16</a>, <a href="2-bw.html#SP17">&#167;17</a>, <a href="2-bw.html#SP19">&#167;19</a>, <a href="2-bw.html#SP21">&#167;21</a>, <a href="2-bw.html#SP23">&#167;23</a>, <a href="2-bw.html#SP24">&#167;24</a>, <a href="2-bw.html#SP25">&#167;25</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">resource_num</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">supplied_filename</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">index</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">data</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP10" class="function-link"><span class="function-syntax">Writer::chunk_type_is_legal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">id</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"tried to complete non-Blorb chunk"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP10" class="function-link"><span class="function-syntax">Writer::index_entry_is_legal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">index</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"tried to include mis-indexed chunk"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Set the filename for the new chunk</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_entry</span><span class="plain-syntax"> = </span><span class="identifier-syntax">index</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_entry</span><span class="plain-syntax">) </span><span class="identifier-syntax">no_indexed_chunks</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">byte_offset</span><span class="plain-syntax"> = </span><span class="identifier-syntax">total_size_of_Blorb_chunks</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resource_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">resource_num</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP8_2" class="named-paragraph-link"><span class="named-paragraph">Compute the size in bytes of the chunk</span><span class="named-paragraph-number">8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP8_3" class="named-paragraph-link"><span class="named-paragraph">Advance the total chunk size</span><span class="named-paragraph-number">8.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Begun chunk %s: fn is &lt;%f&gt; (innate size %d)\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_type</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_file</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>&#167;8.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set the filename for the new chunk</span><span class="named-paragraph-number">8.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">data</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">data_in_memory</span><span class="plain-syntax"> = </span><a href="../foundation/2-mmr.html#SP24" class="function-link"><span class="function-syntax">Memory::malloc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">, </span><span class="constant-syntax">CHUNK_STORAGE_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_file</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">length_of_data_in_memory</span><span class="plain-syntax"> = </span><span class="identifier-syntax">length</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">length</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">data_in_memory</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">data_in_memory</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_file</span><span class="plain-syntax"> = </span><span class="identifier-syntax">supplied_filename</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">length_of_data_in_memory</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2" class="paragraph-anchor"></a><b>&#167;8.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compute the size in bytes of the chunk</span><span class="named-paragraph-number">8.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">data</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">length</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><a href="../foundation/6-bf.html#SP7" class="function-link"><span class="function-syntax">BinaryFiles::size</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">supplied_filename</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP12" class="function-link"><span class="function-syntax">Writer::chunk_type_is_already_an_IFF</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_type</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">size</span><span class="plain-syntax"> += </span><span class="constant-syntax">8</span><span class="plain-syntax">; </span><span class="comment-syntax"> allow 8 further bytes for the chunk header to be added later</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">size</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_3" class="paragraph-anchor"></a><b>&#167;8.3. </b>Note the adjustment of <span class="extract"><span class="extract-syntax">total_size_of_Blorb_chunks</span></span> so as to align the next
chunk's position at a two-byte boundary &mdash; this betrays IFF's origin in the
16-bit world of the mid-1980s. Today's formats would likely align at four, eight
or even sixteen-byte boundaries.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Advance the total chunk size</span><span class="named-paragraph-number">8.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">total_size_of_Blorb_chunks</span><span class="plain-syntax"> += </span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">current_chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax">) % </span><span class="constant-syntax">2</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">total_size_of_Blorb_chunks</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Our choice of chunks.</b>We will generate only the following chunks with the above apparatus. The full
Blorb specification does include others, but Inform doesn't need them.
</p>

<p class="commentary">The weasel words "with the above..." are because we will also generate two
chunks separately: the compulsory <span class="extract"><span class="extract-syntax">"FORM"</span></span> chunk enclosing the entire Blorb, and
an indexing chunk, <span class="extract"><span class="extract-syntax">"RIdx"</span></span>. Within this index, some chunks appear, but not
others, and they are labelled with the "index entry" text.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">legal_Blorb_chunk_types</span><span class="plain-syntax">[] = {</span>
<span class="plain-syntax">    </span><span class="string-syntax">"AUTH"</span><span class="plain-syntax">, </span><span class="string-syntax">"(c) "</span><span class="plain-syntax">, </span><span class="string-syntax">"Fspc"</span><span class="plain-syntax">, </span><span class="string-syntax">"RelN"</span><span class="plain-syntax">, </span><span class="string-syntax">"IFmd"</span><span class="plain-syntax">, </span><span class="comment-syntax"> miscellaneous identifying data</span>
<span class="plain-syntax">    </span><span class="string-syntax">"JPEG"</span><span class="plain-syntax">, </span><span class="string-syntax">"PNG "</span><span class="plain-syntax">, </span><span class="comment-syntax"> images in different formats</span>
<span class="plain-syntax">    </span><span class="string-syntax">"AIFF"</span><span class="plain-syntax">, </span><span class="string-syntax">"OGGV"</span><span class="plain-syntax">, </span><span class="string-syntax">"MIDI"</span><span class="plain-syntax">, </span><span class="string-syntax">"MOD "</span><span class="plain-syntax">, </span><span class="comment-syntax"> sound effects in different formats</span>
<span class="plain-syntax">    </span><span class="string-syntax">"TEXT"</span><span class="plain-syntax">, </span><span class="string-syntax">"BINA"</span><span class="plain-syntax">, </span><span class="comment-syntax"> data files in different formats</span>
<span class="plain-syntax">    </span><span class="string-syntax">"ZCOD"</span><span class="plain-syntax">, </span><span class="string-syntax">"GLUL"</span><span class="plain-syntax">, </span><span class="comment-syntax"> story files in different formats</span>
<span class="plain-syntax">    </span><span class="string-syntax">"RDes"</span><span class="plain-syntax">, </span><span class="comment-syntax"> resource descriptions (added to the standard in March 2014)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">NULL</span><span class="plain-syntax"> };</span>

<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">legal_Blorb_index_entries</span><span class="plain-syntax">[] = {</span>
<span class="plain-syntax">    </span><span class="string-syntax">"Pict"</span><span class="plain-syntax">, </span><span class="string-syntax">"Snd "</span><span class="plain-syntax">, </span><span class="string-syntax">"Exec"</span><span class="plain-syntax">, </span><span class="string-syntax">"Data"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax"> };</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Because we are wisely paranoid:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::chunk_type_is_legal</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Writer::chunk_type_is_legal</span></span>:<br/><a href="2-bw.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">type</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">legal_Blorb_chunk_types</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">legal_Blorb_chunk_types</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::index_entry_is_legal</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Writer::index_entry_is_legal</span></span>:<br/><a href="2-bw.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">entry</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">entry</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">legal_Blorb_index_entries</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">legal_Blorb_index_entries</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>This function checks a linked list to see if a resource number is used twice.
If so, TRUE is returned and the rest of the program is expected to immediately
exit with a fatal error. Otherwise, FALSE is returned, indicating that
everything is fine.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::resource_seen</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Writer::resource_seen</span></span>:<br/><a href="2-bw.html#SP17">&#167;17</a>, <a href="2-bw.html#SP19">&#167;19</a>, <a href="2-bw.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">resource_number</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">rn</span><span class="plain-syntax">, </span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">num</span><span class="plain-syntax"> == </span><span class="identifier-syntax">value</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">num</span><span class="plain-syntax"> = </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">rn</span><span class="plain-syntax">, </span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>Because it will make a difference to how we embed a file into our Blorb,
we need to know whether the chunk in question is already an IFF in its
own right. Only one type of chunk is, as it happens:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::chunk_type_is_already_an_IFF</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Writer::chunk_type_is_already_an_IFF</span></span>:<br/><a href="2-bw.html#SP8_2">&#167;8.2</a>, <a href="2-bw.html#SP26_3">&#167;26.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">, </span><span class="string-syntax">"AIFF"</span><span class="plain-syntax">)==0) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b><span class="extract"><span class="extract-syntax">"AUTH"</span></span>: author's name, as a null-terminated string.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::author_chunk</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Writer::author_chunk</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Author: &lt;%S&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="string-syntax">"AUTH"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b><span class="extract"><span class="extract-syntax">"(c) "</span></span>: copyright declaration.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::copyright_chunk</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Writer::copyright_chunk</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Copyright declaration: &lt;%S&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="string-syntax">"(c) "</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b><span class="extract"><span class="extract-syntax">"Fspc"</span></span>: frontispiece image ID number &mdash; which picture resource provides
cover art, in other words.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::frontispiece_chunk</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Writer::frontispiece_chunk</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2_1">&#167;7.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Frontispiece is image %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">data</span><span class="plain-syntax">[4];</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::s_four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">data</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Fspc"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">data</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b><span class="extract"><span class="extract-syntax">"RelN"</span></span>: release number.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::release_chunk</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Writer::release_chunk</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Release number is %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">rn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">data</span><span class="plain-syntax">[2];</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::s_two_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">data</span><span class="plain-syntax">, </span><span class="identifier-syntax">rn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="string-syntax">"RelN"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">data</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b><span class="extract"><span class="extract-syntax">"Pict"</span></span>: a picture, or image. This must be available as a binary file on
disc, and in a format which Blorb allows: for Inform 7 use, this will always
be PNG or JPEG. There can be any number of these chunks.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::picture_chunk</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Writer::picture_chunk</span></span>:<br/><a href="2-bw.html#SP18">&#167;18</a><br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"PNG "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">form</span><span class="plain-syntax"> = </span><a href="../foundation/3-fln.html#SP9" class="function-link"><span class="function-syntax">Filenames::guess_format</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_JPEG</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"JPEG"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_PNG</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"PNG "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="1-be.html#SP3" class="function-link"><span class="function-syntax">BlorbErrors::error_1f</span></a><span class="plain-syntax">(</span><span class="string-syntax">"image file has unknown file extension "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"(expected e.g. '.png' for PNG, '.jpeg' for JPEG)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Picture resource number is less than 1"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pict_resource</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">pict_resource</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP11" class="function-link"><span class="function-syntax">Writer::resource_seen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pict_resource</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Duplicate Picture resource number"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="string-syntax">"Pict"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">)+1;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_Cs</span><span class="plain-syntax"> = </span><a href="../foundation/2-mmr.html#SP24" class="function-link"><span class="function-syntax">Memory::malloc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="constant-syntax">STRING_STORAGE_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="../foundation/4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_ISO_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt_Cs</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-bw.html#SP23" class="function-link"><span class="function-syntax">Writer::add_rdes_record</span></a><span class="plain-syntax">(1, </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt_Cs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">no_pictures_included</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>For images identified by name. The older Blorb creation program, <span class="extract"><span class="extract-syntax">perlBlorb</span></span>,
would emit helpful I6 constant declarations, allowing the programmer to
include these an I6 source file and then write, say, <span class="extract"><span class="extract-syntax">PlaySound(SOUND_Boom)</span></span>
rather than <span class="extract"><span class="extract-syntax">PlaySound(5)</span></span>. (Whenever the Blurb file is changed, the constants
must be included again.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::picture_chunk_text</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Writer::picture_chunk_text</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Null picture ID, using %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">picture_resource_num</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant PICTURE_%S = %d;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">picture_resource_num</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">picture_resource_num</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP17" class="function-link"><span class="function-syntax">Writer::picture_chunk</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">picture_resource_num</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">""</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b><span class="extract"><span class="extract-syntax">"Snd "</span></span>: a sound effect. This must be available as a binary file on
disc, and in a format which Blorb allows: for Inform 7 use, this is officially
Ogg Vorbis or AIFF at present, but there has been repeated discussion about
adding MOD ("SoundTracker") or MIDI files, so both are supported here.
</p>

<p class="commentary">There can be any number of these chunks, too.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::sound_chunk</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Writer::sound_chunk</span></span>:<br/><a href="2-bw.html#SP20">&#167;20</a><br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"AIFF"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">form</span><span class="plain-syntax"> = </span><a href="../foundation/3-fln.html#SP9" class="function-link"><span class="function-syntax">Filenames::guess_format</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_OGG</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"OGGV"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_MIDI</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"MIDI"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_MOD</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"MOD "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_AIFF</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"AIFF"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="1-be.html#SP3" class="function-link"><span class="function-syntax">BlorbErrors::error_1f</span></a><span class="plain-syntax">(</span><span class="string-syntax">"sound file has unknown file extension "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"(expected e.g. '.ogg', '.midi', '.mod' or '.aiff', as appropriate)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Sound resource number is less than 3"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sound_resource</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">sound_resource</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP11" class="function-link"><span class="function-syntax">Writer::resource_seen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sound_resource</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">)) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Duplicate Sound resource number"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="string-syntax">"Snd "</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">)+1;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_Cs</span><span class="plain-syntax"> = </span><a href="../foundation/2-mmr.html#SP24" class="function-link"><span class="function-syntax">Memory::malloc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="constant-syntax">STRING_STORAGE_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="../foundation/4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_ISO_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt_Cs</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-bw.html#SP23" class="function-link"><span class="function-syntax">Writer::add_rdes_record</span></a><span class="plain-syntax">(2, </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt_Cs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">no_sounds_included</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>And again, by name:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::sound_chunk_text</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Writer::sound_chunk_text</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Null sound ID, using %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sound_resource_num</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant SOUND_%S = %d;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">sound_resource_num</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">sound_resource_num</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP19" class="function-link"><span class="function-syntax">Writer::sound_chunk</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sound_resource_num</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">""</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b>Data files are essentially the same, but have no alt-texts, and use their
own index and format types:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::data_chunk</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Writer::data_chunk</span></span>:<br/><a href="2-bw.html#SP22">&#167;22</a><br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">format</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"BINA"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq_insensitive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">format</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"BINA"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"BINA"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq_insensitive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">format</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"TEXT"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"TEXT"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Invalid data file format: not BINA or TEXT"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Data resource number is less than 1"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">data_resource</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">data_resource</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">resource_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP11" class="function-link"><span class="function-syntax">Writer::resource_seen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">data_resource</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">)) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Duplicate Data resource number"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="string-syntax">"Data"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">no_data_files_included</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>And again, by name:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::data_chunk_text</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Writer::data_chunk_text</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">format</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Null data file ID, using %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">data_file_resource_num</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant DATA_%S = %d;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">data_file_resource_num</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">data_file_resource_num</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP21" class="function-link"><span class="function-syntax">Writer::data_chunk</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">data_file_resource_num</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">format</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b><span class="extract"><span class="extract-syntax">"RDes"</span></span>: the resource description, a repository for alt-texts describing
images or sounds.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_of_rdes_chunk</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::add_rdes_record</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Writer::add_rdes_record</span></span>:<br/><a href="2-bw.html#SP17">&#167;17</a>, <a href="2-bw.html#SP19">&#167;19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">usage</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">usage</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resource_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">description</span><span class="plain-syntax"> = </span><a href="../foundation/4-cst.html#SP11" class="function-link"><span class="function-syntax">CStrings::park_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">size_of_rdes_chunk</span><span class="plain-syntax"> += </span><span class="constant-syntax">12</span><span class="plain-syntax"> + (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><a href="../foundation/4-cst.html#SP2" class="function-link"><span class="function-syntax">CStrings::strlen_unbounded</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::rdes_chunk</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Writer::rdes_chunk</span></span>:<br/><a href="2-bw.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">size_of_rdes_chunk</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) </span><a href="../foundation/2-mmr.html#SP24" class="function-link"><span class="function-syntax">Memory::malloc</span></a><span class="plain-syntax">((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">size_of_rdes_chunk</span><span class="plain-syntax"> + </span><span class="constant-syntax">9</span><span class="plain-syntax">, </span><span class="constant-syntax">RDES_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"Run out of memory"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::s_four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax">, </span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rr</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">rr</span><span class="plain-syntax">, </span><span class="reserved-syntax">rdes_record</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usage</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">((</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) (</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="string-syntax">"Pict"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usage</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">((</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) (</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="string-syntax">"Snd "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::s_four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::s_four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> + </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resource_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::s_four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> + </span><span class="constant-syntax">8</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">description</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">((</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) (</span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> + </span><span class="constant-syntax">12</span><span class="plain-syntax">), </span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">description</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> += </span><span class="constant-syntax">12</span><span class="plain-syntax"> + (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">description</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pos</span><span class="plain-syntax"> != </span><span class="identifier-syntax">size_of_rdes_chunk</span><span class="plain-syntax"> + </span><span class="constant-syntax">4</span><span class="plain-syntax">) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"misconstructed rdes"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="string-syntax">"RDes"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">rdes_data</span><span class="plain-syntax">, (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b><span class="extract"><span class="extract-syntax">"Exec"</span></span>: the executable program, which will normally be a Z-machine or
Glulx story file. It's legal to make a blorb with no story file in, but
Inform 7 never does this.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::executable_chunk</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">Writer::executable_chunk</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"ZCOD"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">form</span><span class="plain-syntax"> = </span><a href="../foundation/3-fln.html#SP9" class="function-link"><span class="function-syntax">Filenames::guess_format</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_GLULX</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"GLUL"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FORMAT_PERHAPS_ZCODE</span><span class="plain-syntax">) </span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="string-syntax">"ZCOD"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="1-be.html#SP3" class="function-link"><span class="function-syntax">BlorbErrors::error_1f</span></a><span class="plain-syntax">(</span><span class="string-syntax">"story file has unknown file extension "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"(expected e.g. '.z5' for Z-code, '.ulx' for Glulx)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="string-syntax">"Exec"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b><span class="extract"><span class="extract-syntax">"IFmd"</span></span>: the bibliographic data (or "metadata") about the work of IF
being blorbed up, in the form of an iFiction record. (The format of which
is set out in the "Treaty of Babel" agreement.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::metadata_chunk</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Writer::metadata_chunk</span></span>:<br/>Blurb Parser - <a href="1-bp.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP8" class="function-link"><span class="function-syntax">Writer::add_chunk_to_blorb</span></a><span class="plain-syntax">(</span><span class="string-syntax">"IFmd"</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. Main construction.</b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Writer::write_blorb_file</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">Writer::write_blorb_file</span></span>:<br/>Main - <a href="1-mn.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">out</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP23" class="function-link"><span class="function-syntax">Writer::rdes_chunk</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IFF</span><span class="plain-syntax"> = </span><a href="../foundation/6-bf.html#SP8" class="function-link"><span class="function-syntax">BinaryFiles::open_for_writing</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">out</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">RIdx_size</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_byte_after_index</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP26_1" class="named-paragraph-link"><span class="named-paragraph">Calculate the sizes of the whole file and the index chunk</span><span class="named-paragraph-number">26.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP26_2" class="named-paragraph-link"><span class="named-paragraph">Write the initial FORM chunk of the IFF file, and then the index</span><span class="named-paragraph-number">26.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP26_4" class="named-paragraph-link"><span class="named-paragraph">Print out a copy of the chunk table</span><span class="named-paragraph-number">26.4</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">, </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP26_3" class="named-paragraph-link"><span class="named-paragraph">Write the chunk</span><span class="named-paragraph-number">26.3</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><a href="../foundation/6-bf.html#SP8" class="function-link"><span class="function-syntax">BinaryFiles::close</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26_1" class="paragraph-anchor"></a><b>&#167;26.1. </b>The bane of IFF file generation is that each chunk has to be marked
up-front with an offset to skip past it. This means that, unlike with XML
or other files having flexible-sized ingredients delimited by begin-end
markers, we always have to know the length of a chunk before we start
writing it.
</p>

<p class="commentary">That even extends to the file itself, which is a single IFF chunk of type
<span class="extract"><span class="extract-syntax">"FORM"</span></span>. So we need to think carefully. We will need the <span class="extract"><span class="extract-syntax">FORM</span></span> header,
then the header for the <span class="extract"><span class="extract-syntax">RIdx</span></span> indexing chunk, then the body of that indexing
chunk &mdash; with one record for each indexed chunk; and then room for all of
the chunks we'll copy in, whether they are indexed or not.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate the sizes of the whole file and the index chunk</span><span class="named-paragraph-number">26.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">FORM_header_size</span><span class="plain-syntax"> = </span><span class="constant-syntax">12</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">RIdx_header_size</span><span class="plain-syntax"> = </span><span class="constant-syntax">12</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">index_entry_size</span><span class="plain-syntax"> = </span><span class="constant-syntax">12</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">RIdx_size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RIdx_header_size</span><span class="plain-syntax"> + </span><span class="identifier-syntax">index_entry_size</span><span class="plain-syntax">*</span><span class="identifier-syntax">no_indexed_chunks</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">first_byte_after_index</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FORM_header_size</span><span class="plain-syntax"> + </span><span class="identifier-syntax">RIdx_size</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">blorb_file_size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_byte_after_index</span><span class="plain-syntax"> + </span><span class="identifier-syntax">total_size_of_Blorb_chunks</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP26">&#167;26</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2" class="paragraph-anchor"></a><b>&#167;26.2. </b>Each different IFF file format is supposed to provide its own "magic text"
identifying what the file format is, and for Blorbs that text is "IFRS",
short for "IF Resource".
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write the initial FORM chunk of the IFF file, and then the index</span><span class="named-paragraph-number">26.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">fprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="string-syntax">"FORM"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">blorb_file_size</span><span class="plain-syntax"> - </span><span class="constant-syntax">8</span><span class="plain-syntax">); </span><span class="comment-syntax"> offset to end of </span><span class="extract"><span class="extract-syntax">FORM</span></span><span class="comment-syntax"> after the 8 bytes so far</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="string-syntax">"IFRS"</span><span class="plain-syntax">); </span><span class="comment-syntax"> magic text identifying the IFF as a Blorb</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">fprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="string-syntax">"RIdx"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">RIdx_size</span><span class="plain-syntax"> - </span><span class="constant-syntax">8</span><span class="plain-syntax">); </span><span class="comment-syntax"> offset to end of </span><span class="extract"><span class="extract-syntax">RIdx</span></span><span class="comment-syntax"> after the 8 bytes so far</span>
<span class="plain-syntax">    </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_indexed_chunks</span><span class="plain-syntax">); </span><span class="comment-syntax"> i.e., number of entries in the index</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">, </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_entry</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">fprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="string-syntax">"%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resource_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">first_byte_after_index</span><span class="plain-syntax"> + </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">byte_offset</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP26">&#167;26</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3" class="paragraph-anchor"></a><b>&#167;26.3. </b>Most of the chunks we put in exist on disc without their headers, but AIFF
sound files are an exception, because those are IFF files in their own right;
so they come with ready-made headers.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write the chunk</span><span class="named-paragraph-number">26.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bytes_to_copy</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_type</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-bw.html#SP12" class="function-link"><span class="function-syntax">Writer::chunk_type_is_already_an_IFF</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">type</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">fprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="string-syntax">"%s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">type</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::four_word</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax"> - </span><span class="constant-syntax">8</span><span class="plain-syntax">); </span><span class="comment-syntax"> offset to end of chunk after the 8 bytes so far</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">bytes_to_copy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax"> - </span><span class="constant-syntax">8</span><span class="plain-syntax">; </span><span class="comment-syntax"> since here the chunk size included 8 extra</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">bytes_to_copy</span><span class="plain-syntax"> = </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax">; </span><span class="comment-syntax"> whereas here the chunk size was genuinely the file size</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">length_of_data_in_memory</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP26_3_2" class="named-paragraph-link"><span class="named-paragraph">Copy that many bytes from memory</span><span class="named-paragraph-number">26.3.2</span></a></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="2-bw.html#SP26_3_1" class="named-paragraph-link"><span class="named-paragraph">Copy that many bytes from the chunk file on the disc</span><span class="named-paragraph-number">26.3.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">bytes_to_copy</span><span class="plain-syntax"> % </span><span class="constant-syntax">2</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::one_byte</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="comment-syntax"> as we allowed for above</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP26">&#167;26</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3_1" class="paragraph-anchor"></a><b>&#167;26.3.1. </b>Sometimes the chunk's contents are on disc:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Copy that many bytes from the chunk file on the disc</span><span class="named-paragraph-number">26.3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">CHUNKSUB</span><span class="plain-syntax"> = </span><a href="../foundation/6-bf.html#SP8" class="function-link"><span class="function-syntax">BinaryFiles::open_for_reading</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">bytes_to_copy</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fgetc</span><span class="plain-syntax">(</span><span class="identifier-syntax">CHUNKSUB</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">) </span><a href="1-be.html#SP2" class="function-link"><span class="function-syntax">BlorbErrors::fatal_fs</span></a><span class="plain-syntax">(</span><span class="string-syntax">"chunk ran out incomplete"</span><span class="plain-syntax">, </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::one_byte</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="../foundation/6-bf.html#SP8" class="function-link"><span class="function-syntax">BinaryFiles::close</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">CHUNKSUB</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP26_3">&#167;26.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_3_2" class="paragraph-anchor"></a><b>&#167;26.3.2. </b>And sometimes, for shorter things, they are in memory:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Copy that many bytes from memory</span><span class="named-paragraph-number">26.3.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">data_in_memory</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">bytes_to_copy</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) (</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">data_in_memory</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax">            </span><a href="2-bw.html#SP6" class="function-link"><span class="function-syntax">Writer::one_byte</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IFF</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP26_3">&#167;26.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_4" class="paragraph-anchor"></a><b>&#167;26.4. </b>For debugging purposes only:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Print out a copy of the chunk table</span><span class="named-paragraph-number">26.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Chunk table:\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">, </span><span class="reserved-syntax">chunk_metadata</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! Chunk %s %06x %s %d &lt;%f&gt;\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_type</span><span class="plain-syntax">, </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">size</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_entry</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_entry</span><span class="plain-syntax">):</span><span class="string-syntax">"unindexed"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">resource_id</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">chunk</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chunk_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"! End of chunk table\n"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-bw.html#SP26">&#167;26</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="1-bp.html">&#10094;</a></li><li class="progresschapter"><a href="M-ui.html">M</a></li><li class="progresschapter"><a href="1-bsc.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresscurrent">bw</li><li class="progresschapter"><a href="3-rls.html">3</a></li><li class="progressnext"><a href="3-rls.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

